<?php

include_once 'constants.php';

/**
 * Clase para el manejo de interacciones de base de datos con PDO.
 *
 * @author Anyul Rivas
 */
class db_pdo {

    private $dsn = DSN;
    private $username = USER;
    private $password = PASSWORD;
    private $pdo;

    public function __construct() {
        try {
            $this->pdo = new PDO($this->dsn, $this->username, $this->password);
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->pdo->exec("set names utf8");
        } catch (Exception $exc) {
            trigger_error($exc->getMessage());
        }
    }

    /**
     * Realiza una consulta
     * @param String $query consulta sql
     * @return mixed resultado
     * @throws Exception 
     */
    public function query($query) {
        $result = $this->pdo->query($query);
        $result->execute();
        if ($result->errorCode() == "0000") {
            return $result->fetchAll(PDO::FETCH_OBJ);
        } else {
            $excepcion = $result->errorInfo();
            throw new Exception("Error en Query: " . $excepcion[2]);
        }
    }

    /**
     * realiza una consulta preparada
     * @param String $select consulta
     * @param Array $variables arreglo con variables de entrada
     * @see pdo_parametro
     * @return PDOStatement registros
     * @throws Exception
     */
    public function prepare($select, $variables) {
        $result = $this->pdo->prepare($select);
        $result->execute($variables);
        if ($result->errorCode() == "0000") {
            return $result->fetchAll(PDO::FETCH_OBJ);
        } else {
            $excepcion = $result->errorInfo();
            throw new Exception("Error en Query: " . $excepcion[2]);
        }
    }

    /**
     * realiza una consulta preparada con parametros de entrada tpados
     * @param String $select consulta
     * @param Array $variables arreglo de entrada, del tipo pdo_parametro
     * @see pdo_parametro
     * @return PDOStatement registros
     * @throws Exception
     */
    public function prepare_type($select, $variables = null) {
        try {
            $result = $this->pdo->prepare($select);
            if (is_array($variables)) {
                foreach ($variables as $parametro) {
                    $result->bindParam($parametro->nombre, $parametro->valor, $parametro->tipo, $parametro->longitud);
                }
            }
            $result->execute();
            if ($result->errorCode() == "0000") {
                return $result->fetchAll(PDO::FETCH_OBJ);
            } else {
                $excepcion = $result->errorInfo();
                throw new Exception("Error en Query: " . $excepcion[2]);
            }
        } catch (Exception $exc) {
            trigger_error("Error al ejecutar consulta: " . $exc->getMessage() . " | ");
        }
    }

    public function exec($query) {
        $result = $this->pdo->exec($query);
        if ($this->pdo->errorCode() == '0000') {
            return $result;
        } else {
            $error = $this->pdo->errorInfo();
            throw new Exception("ejecucion fallida:" . $error[2]);
        }
    }

    public function __destruct() {
        unset($this->pdo);
    }

}

/**
 * Representa un parametro tipado para las consultas preparadas
 */
class pdo_parametro {

    public $nombre;
    public $valor;
    public $tipo;
    public $longitud;

    public function __construct($nombre, $valor, $tipo = null, $longitud = null) {
        $this->nombre = $nombre;
        $this->valor = $valor;
        $this->longitud = $longitud;
        $this->tipo = $tipo == null ? PDO::PARAM_STR : $tipo;
    }

}

?>
